#!/usr/bin/python3
# -*- coding:utf-8 -*-
""""
@Author: 李吉凯
@Email: lijk34925@hundsun.com
@Time: 2022/5/12 10:31
@File: 步骤检查.py
"""
import re

from qturboframe.lib.utils.by import By

from BladeFerm.Lib.Common import logger
from qturboframe.lib.webdriver import SeleniumError
from BladeFerm.hui2_app import FE
from BladeFerm.hui2_app.check import check_of_text, check_dialog_of_text, assert_except



def check_ele_text(input_data=None, ui_expect=None):
    '''
    检查文本不存在与否？一般可用于判断页面上加载的元素是否出现？
    :param input_data:
    :param ui_expect: {'期望结果': '首页', '辅助属性': 'class:nick-name'}
    :return:
    '''
    result = check_of_text(text=ui_expect.get('期望结果'), assist=ui_expect.get('辅助属性', ''))
    if not result:
        raise SeleniumError(f"检查期望元素： {ui_expect} 未找到！")


def check_ele_no_text(input_data=None, ui_expect=None):
    result = check_of_text(text=ui_expect.get('期望结果'), assist=ui_expect.get('辅助属性', ''))
    if result:
        raise SeleniumError(f"检查期望元素： {ui_expect} 未找到！")


def check_table_rows(input_data: dict, ui_expect=None):
    '''
    检查表格的行数。
    :param input_data:
    :param ui_expect:
    :return: -1 表示未检查。检查通过，返回具体的行数，与期望不一致则直接报错
    '''
    rows_exp = ui_expect.pop('期望行数', -1) if isinstance(ui_expect, dict) else -1
    title_name = input_data.get('title_name', '')
    if title_name:
        id_name = {
            By.XPATH: f'//div[@class="h-table-cell"]/span[contains(text(),"{title_name}")]//ancestor::div[@class="h-table-wrapper"]//table'}
        table_obj = FE.table_new(idname=id_name)
    else:
        table_obj = FE.table_new()
    flag = table_obj.check_load_status()
    if not flag:
        logger.warning(f'表格行数据加载超时！')
    res_rows = table_obj.get_rows_in_page()
    if int(rows_exp) == res_rows and rows_exp != -1:
        logger.info(f'检查与期望行数{res_rows}一致，断言通过。')
        return res_rows
    elif int(rows_exp) != res_rows and rows_exp != -1:
        logger.error(f'校验失败！期望行数 {rows_exp} 与实际的行数 {res_rows} 不一致！')
        raise SeleniumError(f'校验失败！期望行数 {rows_exp} 与实际的行数 {res_rows} 不一致！')
    else:
        logger.info(f'未得到期望行数，不进行检查!查询当前行数为{res_rows}')
        return res_rows



def check_table(input_data: dict, ui_expect=None):
    '''
    表格数据检查

    :uiexpect:
        - 表格列名: 表格列名值
          期望行数: -1  【不给的话默认-1，不检查。要是期望0行，则不进行数据校验。大于0行时才校验数据】
    '''
    msgBox = FE.msg_box(idname={By.CSS_SELECTOR: 'div.h-message'}, timeout=1)
    flag = msgBox.exist()
    if flag:
        content = msgBox.get_text()
        raise SeleniumError(f"检查出现错误弹框，内容为：{content}")
    else:
        res_rows = check_table_rows(input_data, ui_expect)
        if not ui_expect and res_rows == 0:
            return None
        elif ui_expect and res_rows == 0:
            error = "查询结果为0行，不符合期望，无法继续断言！"
            logger.error(error)
            raise SeleniumError(error)
        else:
            title_name = input_data.get('title_name', '')
            if title_name:
                id_name = {By.XPATH: f'//div[@class="h-table-cell"]/span[contains(text(),"{title_name}")]'
                                     f'//ancestor::div[@class="h-table-wrapper"]//table'}
                table = FE.table_new(idname=id_name)
            else:
                table = FE.table_new()
            table.checkData(ui_expect, 2)
            return table


def check_table_no_exist(input_data:dict, ui_expect=None):
    '''
        表格数据检查,元素不存在返回true

        :uiexpect:
            - 表格列名: 表格列名值
              期望行数: -1  【不给的话默认-1，不检查。要是期望0行，则不进行数据校验。大于0行时才校验数据】
    '''
    keyList = []
    for key, value in ui_expect.items():
        keyList.append(key)
    temp = FE.table()._get_row_index([], keyList, ui_expect)
    logger.info(temp)
    if temp == 0:
        pass
    else:
        raise SeleniumError("表格内容校验失败")


def check_dialog_message(input_data=None, ui_expect=None):
    text = ui_expect.get('期望文本', '导出提示')
    exp_res = ui_expect.get('期望结果', '是')
    res = check_dialog_of_text(idname={By.XPATH: f'.//*[text()="{text}"]'}, driver=FE.current_page().element)
    assert_except(res, exp_res == "是", '导出文件确认弹框')



# def check_tips(ui_expect):
#     '''
#     检查输入框弹出提示，
#     ui_expect为字典类型
#     key:输入框前面的label名称
#     value:输入框弹出的提示
#     例如：场景类型；输入框不能为空
#     '''
#     for key, value in ui_expect.items():
#         if value == '' or value == ' ':
#             pass
#         else:
#             text = get_div_title(key)
#             if value in text:
#                 pass
#             else:
#                 raise SeleniumError("输入框校验失败")


def check_msg_box(ui_expect):
    '''
        检查消息弹出框提示，
        ui_expect为字典类型
        key:弹出提示
        value:提示信息
        例如：弹出提示；场景信息不能重复
        '''
    text = FE.button(idname={'xpath': '//div[@class="h-message-notice-content"]/descendant::span'}).get_text()
    if ui_expect.get('弹出提示') in text:
        pass
    else:
        raise SeleniumError("弹出框校验失败")


# 通用的断言功能脚本
def common_assert_except(result_list: dict, ui_expect: dict):
    """
    通用的断言功能脚本
    :param result_list: 查询的结果列表 [{k:v},{...}]
    :param ui_expect: 用例输入的期望
    :return:
    """
    def __judge_number(val):
        try:
            float(val)
            return True
        except ValueError:
            return False
    for key, value in ui_expect.items():
        for row in result_list:
            real_value = row.get(key.upper(), None)
            if real_value and __judge_number(value) and __judge_number(real_value):
                diff = float(value) - float(real_value)
                if abs(diff) < 0.1:
                    logger.info(f'断言成功，{key}的预期值和实际值一致！')
                else:
                    error = f'{key}的预期值和实际值不一致，预期值：{value}，实际值：{real_value}！'
                    logger.error(error)
                    raise SeleniumError(error)
            elif real_value and re.search(value, real_value, re.I):
                logger.info(f'断言成功，{key}的预期值和实际值一致！')
            elif (value == '0' or value == 0) and real_value is None:
                logger.info(f'断言成功，指标不预警！')
            else:
                error = f'{key}的预期值和实际值不一致，预期值：{value}，实际值：{real_value}！'
                logger.error(error)
                raise SeleniumError(error)